﻿using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;

namespace XFABManager
{

    /// <summary>
    /// 下载文件的请求
    /// </summary>
    public class DownloadFileRequest : CustomAsyncOperation<DownloadFileRequest>
    {

        public const string tempSuffix = ".tempFile";
        //private static int CurrentDownloadFileCount = 0;
        //private const int MAX_DOWNLOAD_FILE_COUNT = 6; // 同时最多下载的文件数量

        private const int DOWNLOAD_FILE_TIME_OUT = 5; // 下载文件的超时时间

        private string file_url;
        private string localfile;
        //private long length;
        private string tempfile;                // 下载的临时文件路径
        private float lastProgress = 0;


        /// <summary>
        /// 下载速度 字节/每秒
        /// </summary>
        public long Speed { get; private set; }

        /// <summary>
        /// 已经下载的文件大小
        /// </summary>
        public long DownloadedSize { get; private set; }

        /// <summary>
        /// 当前下载的文件总大小
        /// </summary>
        public long AllSize { get; private set; }

        /// <summary>
        /// 当前正在下载的文件地址
        /// </summary>
        public string Url => file_url;

        public DownloadFileRequest(string file_url, string localfile, long length = 0)
        {
            this.file_url = file_url;
            this.localfile = localfile;
            //this.length = length;
            tempfile = string.Format("{0}{1}", localfile, tempSuffix);
        }

        private IEnumerator Download()
        { 
            UnityWebRequest downloadFile = UnityWebRequest.Get(this.file_url);
            DownloadHandlerFileRange downloadHandler = new DownloadHandlerFileRange(tempfile, downloadFile);
            downloadFile.downloadHandler = downloadHandler;
            UnityWebRequestAsyncOperation asyncOperation = downloadFile.SendWebRequest();

            float timer = 0;

            while (!asyncOperation.isDone)
            {
                yield return null;
                progress = downloadFile.downloadProgress;
                 
                double detalLength = ((progress - lastProgress) * downloadHandler.FileSize);

                // 计算网速
                Speed = (long)(detalLength / Time.deltaTime);

                if (Speed > downloadHandler.FileSize)
                {
                    Speed = downloadHandler.FileSize;
                }

                if (Speed < 0) { Speed = 0; }

                lastProgress = progress;
                  
                DownloadedSize = downloadHandler.DownloadedSize;
                AllSize = downloadHandler.FileSize;

                // 添加超时逻辑
                if (detalLength == 0) // 当前下载速度为0 开始计时
                {
                    timer += Time.deltaTime;
                    if (timer >= DOWNLOAD_FILE_TIME_OUT) {
                        downloadFile.Abort();
                        break;
                    }
                }
                else {
                    timer = 0;
                }
            }
            
            ((DownloadHandlerFileRange)downloadFile.downloadHandler).Clean();

            if (timer >= DOWNLOAD_FILE_TIME_OUT)
            { 
                Completed(string.Format("下载文件超时:{0}", file_url));
                yield break;
            }

            // 如果是416 说明本地文件已经下载完成
            if (!string.IsNullOrEmpty(downloadFile.error) && downloadFile.responseCode != 416)
            {
                Completed(downloadFile.error);
                yield break;
            }

            // 说明已经下载完成 但是没有把临时文件转成正式文件
            if (File.Exists(localfile))
                File.Delete(localfile);
              
            File.Move(tempfile, localfile); 
            Completed();
        }
        protected override void OnCompleted()
        {
            base.OnCompleted();
            //CurrentDownloadFileCount--;
        }

        public static DownloadFileRequest Download(string file_url, string localfile, long length = 0)
        {

            string key = string.Format("DownloadFileRequest:{0}", file_url);
            return AssetBundleManager.ExecuteOnlyOnceAtATime<DownloadFileRequest>(key, () => {
                DownloadFileRequest request = new DownloadFileRequest(file_url, localfile, length);
                CoroutineStarter.Start(request.Download());
                return request;
            });

        }

        //public static DownloadFileRequest DownloadFile(string file_url, string localfile)
        //{
        //    string key = string.Format("DownloadFile:{0}", file_url);
        //    return AssetBundleManager.ExecuteOnlyOnceAtATime<DownloadFileRequest>(key, () => {
        //        DownloadFileRequest downloadFileRequest = new DownloadFileRequest();
        //        CoroutineStarter.Start(downloadFileRequest.Download(file_url, localfile));
        //        return downloadFileRequest;
        //    });
        //}


    }

}

